package com.gmako.utils;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * 如期工具类
 * @author 「天巧星」燕青
 *
 */
public class DateUtils {
	public static Calendar cal = Calendar.getInstance();

	/**
	 * 获取年
	 * @author 「天巧星」燕青
	 * @return
	 */
	public static int getYear() {
		Calendar cal = Calendar.getInstance();
		return cal.get(Calendar.YEAR);
	}

	/**
	 * 获取月
	 * @author 「天巧星」燕青
	 * @return
	 */
	public static int getMonth() {
		return cal.get(Calendar.MONTH) + 1;
	}

	/**
	 * 获取日
	 * @author 「天巧星」燕青
	 * @return
	 */
	public static int getDay() {
		return cal.get(Calendar.DATE);
	}

	/**
	 * 获取时
	 * @author 「天巧星」燕青
	 * @return
	 */
	public static int getHour() {
		return cal.get(Calendar.HOUR_OF_DAY);
	}

	/**
	 * 获取分
	 * @author 「天巧星」燕青
	 * @return
	 */
	public static int getMinute() {
		return cal.get(Calendar.MINUTE);
	}

	/**
	 * 获取秒
	 * @author 「天巧星」燕青
	 * @return
	 */
	public static int getSecond() {
		return cal.get(Calendar.SECOND);
	}

	/**
	 * Calendar转换为Date
	 * @author 「天巧星」燕青
	 * @param c1
	 * @return
	 */
	public static Date calendarToDate() {
		Calendar cal = Calendar.getInstance();
		Date date = null;
		date = cal.getTime();
		return date;
	}

	/**
	 * Date转换为Calendar
	 * @author 「天巧星」燕青
	 * @param c1
	 * @return
	 */
	public static Calendar dateToCalendar(Date d) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(d);
		return cal;
	}

	/**
	 * 默认时间按格式yyyy-MM-dd 精确到day
	 * @author 「天巧星」燕青
	 * @param d
	 * @return
	 */
	public static String dateToString(Date d) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		if (d == null) {
			return "";
		} else {
			return sdf.format(d);
		}
	}

	/**
	 * 返回格式为自定义formate
	 * @author 「天巧星」燕青
	 * @param d
	 * @param formate
	 * @return
	 */
	public static String dateToString(Date d, String formate) {
		SimpleDateFormat sdf = new SimpleDateFormat(formate);
		if (d == null) {
			return "";
		} else {
			return sdf.format(d);
		}
	}

	/**
	 * 中国时间按格式X年X月X日
	 * @author 「天巧星」燕青
	 * @param date
	 * @return
	 */
	public static String dateToStrChinese(Date d) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
		if (d == null) {
			return "";
		} else {
			return sdf.format(d);
		}
	}

	/**
	 * 获取当前时间 精确到秒 yyyy-MM-dd HH:mm:ss
	 * @author 「天巧星」燕青
	 * 
	 * @return
	 */
	public static String getCurrentDateTime() {
		return dateToString(new Date(), "yyyy-MM-dd HH:mm:ss");
	}

	/**
	 * 以yyyy-mm-dd定义的字符串格式 从String转换成DATE类型
	 * @author 「天巧星」燕青
	 * @param date
	 * @param format
	 * @return
	 * @throws ParseException
	 * @throws ParseException
	 */
	public static Date StringToDate(String dateStr) throws ParseException {
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
		Date date = formatter.parse(dateStr);
		return date;
	}

	/**
	 * 以用户自定义的字符串格式 从String转换成DATE类型
	 * @author 「天巧星」燕青
	 * @param date
	 * @param format
	 *            例如 yyyy-mm-dd;yyyy/mm/dd
	 * @return
	 * @throws ParseException
	 */
	public static Date StringToDate(String dateStr, String format)
			throws ParseException {
		SimpleDateFormat df = new SimpleDateFormat(format);
		return df.parse(dateStr);
	}

	/**
	 * 两个时间差格式为yyyy-mm-dd
	 * @author 「天巧星」燕青
	 * @参数为String类型.对参数的先后没有要求
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static long differDay(String date1, String date2) {
		if (date1 == null || date1.equals("")) {
			return 0;
		}
		if (date2 == null || date2.equals("")) {
			return 0;
		}
		// 以yyyy-mm-dd为标准 转换为标准时间
		SimpleDateFormat df = new SimpleDateFormat("yyyy-mm-dd");
		java.util.Date dateA = null;
		java.util.Date mydate = null;
		try {
			dateA = df.parse(date1);
			mydate = df.parse(date2);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		// 求时间差的绝对值 对参数的先后没有要求
		long day = Math.abs((dateA.getTime() - mydate.getTime())
				/ (24 * 60 * 60 * 1000));
		return day;
	}
	
	/**
	 * 获得两个日期之间的天数  参数为Calendar类型
	 * @author 「天巧星」燕青
	 * @param d1
	 * @param d2
	 * @return
	 */
	public static int getDaysBetween(Calendar d1, Calendar d2) {
		if (d1.after(d2)) { // swap dates so that d1 is start and d2 is end
			Calendar swap = d1;
			d1 = d2;
			d2 = swap;
		}
		int days = d2.get(Calendar.DAY_OF_YEAR) - d1.get(Calendar.DAY_OF_YEAR);
		int y2 = d2.get(Calendar.YEAR);
		if (d1.get(Calendar.YEAR) != y2) {
			d1 = (Calendar) d1.clone();
			do {
				days += d1.getActualMaximum(Calendar.DAY_OF_YEAR);// 得到当年的实际天数
				d1.add(Calendar.YEAR, 1);
			} while (d1.get(Calendar.YEAR) != y2);
		}
		return days;
	}
	
	/**
	 * 获得两个日期之间的天数  参数为String类型
	 * @author 「天巧星」燕青
	 * @param d1
	 * @param d2
	 * @return
	 * @throws ParseException 
	 */
	public static int getDaysBetween(String s1, String s2) throws ParseException {
		Date date1 = DateUtils.StringToDate(s1);
		Date date2 = DateUtils.StringToDate(s2);
		Calendar d1 = DateUtils.dateToCalendar(date1);
		Calendar d2 = DateUtils.dateToCalendar(date2);
		if (d1.after(d2)) { // swap dates so that d1 is start and d2 is end
			Calendar swap = d1;
			d1 = d2;
			d2 = swap;
		}
		int days = d2.get(Calendar.DAY_OF_YEAR) - d1.get(Calendar.DAY_OF_YEAR);
		int y2 = d2.get(Calendar.YEAR);
		if (d1.get(Calendar.YEAR) != y2) {
			d1 = (Calendar) d1.clone();
			do {
				days += d1.getActualMaximum(Calendar.DAY_OF_YEAR);// 得到当年的实际天数
				d1.add(Calendar.YEAR, 1);
			} while (d1.get(Calendar.YEAR) != y2);
		}
		return days;
	}
	
	/**
	 * 获取当前时间
	 * @author 「天巧星」燕青
	 * @return
	 */
	public static Date getCurrentDate(){
		return new Date();
	}
	
	/**
	 * 获取当前Timstamp时间类型
	 * @author 「天巧星」燕青
	 * @return
	 */
	public static Timestamp getCurrentTimestamp(){
		return new Timestamp(getCurrentDate().getTime());
	}
	
	
	/**
	 * 获取String 转 Timstamp时间类型
	 * @author 「天巧星」燕青
	 * @return
	 */
	public static Timestamp stringToTimestamp(String dateStr){
		Timestamp ts = Timestamp.valueOf(dateStr);
		return ts;
	}

	
	/**
	 * 获得日期的下一个星期一的日期
	 * @param date
	 * @return
	 * @author 「天巧星」燕青
	 */
	public static Calendar getNextMonday(Calendar date) {
		Calendar result = null;
		result = date;
		do {
			result = (Calendar) result.clone();
			result.add(Calendar.DATE, 1);
		} while (result.get(Calendar.DAY_OF_WEEK) != 2);
		return result;
	} 
	
	/**
	 * 计算2个日期之间的工作日相隔天数
	 * @param d1
	 * 			日期1
	 * @param d2
	 *			日期2 
	 * @return
	 * @author 「天巧星」燕青
	 */
	public static int getWorkingDay(Calendar d1, Calendar d2) {
		int result = -1;
		if (d1.after(d2)) {
			Calendar swap = d1;
			d1 = d2;
			d2 = swap;
		}
		
		//开始日期的日期偏移量
		int charge_start_date = 0;
		//结束日期的日期偏移量
		int charge_end_date = 0;
		// 日期不在同一个日期内
		int stmp;
		int etmp;
		stmp = 7 - d1.get(Calendar.DAY_OF_WEEK);
		etmp = 7 - d2.get(Calendar.DAY_OF_WEEK);
		// 开始日期为星期六和星期日时偏移量为0
		if (stmp != 0 && stmp != 6) {
			charge_start_date = stmp - 1;
		}
		// 结束日期为星期六和星期日时偏移量为0
		if (etmp != 0 && etmp != 6) {
			charge_end_date = etmp - 1;
		}
		result = (getDaysBetween(getNextMonday(d1), getNextMonday(d2)) / 7)
			* 5 + charge_start_date - charge_end_date;
		return result + 1;
	}
	
	/**
	 * 设置日期
	 * 
	 * @param year
	 * 			年
	 * @param month
	 * 			月
	 * @param date
	 * 			日
	 * @return
	 * @author 「天巧星」燕青
	 */
	public static Calendar setCalendar(int year, int month, int date){
		Calendar calendar = Calendar.getInstance();
		calendar.clear();
		calendar.set(year, month - 1, date);
		return calendar;
	}
	
	/**
	 * 获取当月第一天
	 * @author 「天巧星」燕青
	 * @return
	 */
	public static String getFirstDayOfMonth(){
	      java.text.SimpleDateFormat   df   =   new   java.text.SimpleDateFormat("yyyy-MM-dd");       
          GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();    
          gc.set(Calendar.DAY_OF_MONTH, 1);    
          String day_first = df.format(gc.getTime());  
          return day_first;
	}
	
	/**
	 * 获取当月的最后一天
	 * @author 「天巧星」燕青
	 * @return
	 */
	public static String getEndDayOfMonth(){
		 Calendar calendar  =   new  GregorianCalendar();
		 calendar.set( Calendar.DATE,  1 );
		 calendar.roll(Calendar.DATE,  - 1 );
		 SimpleDateFormat simpleFormate  =   new  SimpleDateFormat( " yyyy-MM-dd " );
		 return simpleFormate.format(calendar.getTime());
	}
	
	/**
	 * 获取当前时间的最近的N天
	 * @author 「天巧星」燕青
	 * @param day
	 * @return
	 */
	public static String RecentlyTime(int day) {
        Calendar c=Calendar.getInstance();
        c.add(Calendar.DAY_OF_MONTH, day);
        Date d=c.getTime();
        DateFormat formatter =new SimpleDateFormat("yyyy-MM-dd");
        return formatter.format(d);
	}
	
	/**
	 * 获取当前日期与星期一相差多少天
	 * @author 「天巧星」燕青
	 * @return
	 */
	public static int getMondayPlus(){
		Calendar cl = Calendar.getInstance();
		int dayOfWeek = cl.get(Calendar.DAY_OF_WEEK);
		if(cl.get(Calendar.DAY_OF_WEEK) == 1){
			return -6;
		}else{
			return 2 - dayOfWeek;
		}
	}
	
	/**
	 * 获取当前日期与星期日相差多少天
	 * @author 「天巧星」燕青
	 * @return
	 */
	public static int getSundayPlus(){
		Calendar cl = Calendar.getInstance();
		int dayOfWeek = cl.get(Calendar.DAY_OF_WEEK);
		if(cl.get(Calendar.DAY_OF_WEEK) == 1){
			return 0;
		}else{
			return 8 - dayOfWeek;
		}
	}
	
	/**
	 * 获取当前日期的本周一的日期
	 * @author 「天巧星」燕青
	 * @return
	 */
	public static  String getCurrentMonday(){
		Calendar cl = Calendar.getInstance();
		int dayPlus = DateUtils.getMondayPlus();
		cl.add(Calendar.DATE, dayPlus);
		String moday = DateUtils.dateToString(cl.getTime());
		return moday;
	}
	
	/**
	 * 获取当前日期本周日的日期 
	 * @author 「天巧星」燕青
	 */
	public static String getCurrentSunday(){
		Calendar cl = Calendar.getInstance();
		int dayPlus = DateUtils.getSundayPlus();
		cl.add(Calendar.DATE, dayPlus);
		String sunday = DateUtils.dateToString(cl.getTime());
		return sunday;
	}
	
	/**
	 * 获取24小时后的时间
	 * @author 「天巧星」燕青
	 * @return
	 */
	public static Date getAfter24Hour(){
		return new Date(System.currentTimeMillis() + 86400000);
	}
	
	/**
	 * 获取24小时后的时间
	 * @author 「天巧星」燕青
	 * @return
	 */
	public static Date getBefore24Hour(){
		return new Date(System.currentTimeMillis() - 86400000);
	}
	
	/**
	 * 获取day天后时间
	 * @author 「天巧星」燕青
	 * @param day
	 * @return
	 */
	public static Date getAfterDay(int day){
		return new Date(System.currentTimeMillis() + 86400000L * day);
	}
	
	/**
	 * 将秒转化成友好的时间
	 * @author 天巧星 燕青
	 * @param time
	 * 		秒
	 * @return
	 */
	public static String parseNiceTime(long time){
		String result = "";
		long day = time / 86400;
		if(time > 86400){
			result = day + "天";
		}
		
		time = time - day * 86400;
		
		long hour = time / 3600;
		if(hour > 0){
			result = result + hour + "小时";
		}
		
		time = time - hour * 3600;
		
		long minute = time / 60;
		if(minute > 0){
			result = result + minute + "分";
		}
		
		time = time - minute * 60;
		
		long second = time;
		result = result + second + "秒";
		
		return result;
	}
	
	
	/**
	 * 获取友好的短格式时间差,只显示最大单位
	 * @author 「天巧星」燕青
	 * @param time
	 * 		秒
	 * @return
	 */
	public static String parseShortNiceTime(long time){
		if(time < 60){
			return time + "秒";
		}else{
			time = time / 60;
			if(time < 60){
				return time + "分";
			}else{
				time = time / 60;
				if(time < 60){
					return time + "小时";
				}else{
					return time / 24 + "天";
				}
			}
		}
	}
	
	/**
	 * 时间差取天
	 */
	public static long subtractDate(Date date){
	 	SimpleDateFormat d = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 格式化时间  
	  
        String nowtime = d.format(new Date());// 按以上格式 将当前时间转换成字符串  
        String uptime = d.format(date);// 按以上格式 将当前时间转换成字符串  
        long result = 0;
        try {  
             result = (d.parse(uptime).getTime() - d.parse(nowtime).getTime()) / 86400000;// 当前时间减去测试时间  
                                        // 这个的除以1000得到秒，相应的60000得到分，3600000得到小时  
        } catch (ParseException e) {  
            e.printStackTrace();  
        } 
        return result;
	}
}
